/* timedisc.c */

/****************************************************************************

Very primitive disc performance measures


****************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "swis.h"


/***************************************************************************/

static int drive_num;

static int FS;
static int FS_DiscOp;

enum {
  FS_ADFS = 0,
  FS_SCSI = 1
};

#define SEC_SIZE 512

/***************************************************************************/

static void *check_alloc(int size)

  /* allocates storage - fatal error if insufficient available */

{
  void *res;

  if ((res = malloc(size))==NULL)
  {
    printf("*** Insufficient memory available\n");
    exit(0);
  }

  return res;
}



/***************************************************************************/

int main(int argc, char *argv[])

{
  char *buff;
  int i, nbytes, num, start;
  char ch;
  BOOL random;
  int lo_start, hi_start, num_secs;

 /* determine drive number of interest */
  if (argc < 2)
    drive_num = 4;
  else
    drive_num = atoi(argv[1]);

 /* and what kind of FileCore filing system */
  FS = FS_ADFS;  /* default */
  if (argc >= 3)
  {
    if (strcmp(argv[2], "SCSI") == 0 || strcmp(argv[2], "scsi") == 0)
      FS = FS_SCSI;
  }

 /* set up SWIs accordingly */
  switch (FS)
  {
    case FS_ADFS:
      FS_DiscOp = ADFS_DiscOp;
      break;

    case FS_SCSI:
      FS_DiscOp = SCSIFS_DiscOp;
      break;
  }

  printf("Number of %d-byte sectors to read: ", SEC_SIZE);
  scanf(" %d", &num_secs);
  nbytes = num_secs*SEC_SIZE;

  printf("Enter 'r' for random reads: "); scanf(" %c", &ch);

  random = (ch == 'r' || ch == 'R');
  if (random)
  {
    printf("Enter lowest possible sector:  "); scanf(" %d", &lo_start);
    printf("Enter highest possible sector: "); scanf(" %d", &hi_start);
    buff = check_alloc(SEC_SIZE);
  }
  else
  {
    printf("Enter start sector for contiguous read: "); scanf(" %d", &start);
    start *= SEC_SIZE;
    buff = check_alloc(nbytes);
  }


  printf("Number of repeats: "); scanf(" %d", &num);

  for (i=0; i<num; i++)
  {
    int time1, time2, j;

   /* read time */
    time1 =_swi(OS_ReadMonotonicTime, R0);

    if (random)
    {
      for (j=0; j<num_secs; j++)
      {
        start = (lo_start + rand()%(hi_start-lo_start))*SEC_SIZE;
       /* read one sector */
        _swi(FS_DiscOp, I1|I2|I3|I4,
              1,                           /* read sectors */
              (drive_num << 29) + start,
              (int)buff,
              SEC_SIZE
            );
      }
    }
    else
    {
     /* read data from disc to buffer */
      _swi(FS_DiscOp, I1|I2|I3|I4,
            1,                           /* read sectors */
            (drive_num << 29) + start,
            (int)buff,
            nbytes
          );
    }

   /* read time */
    time2 = _swi(OS_ReadMonotonicTime, R0);

   /* calculate and print transfer rate */
/*    printf("Time taken = %d centiseconds\n", time2-time1);  */
    printf("Average transfer rate = %.3f Mbytes per second\n",
              ((float)nbytes)*100.0/(((float)(time2-time1))*1048576.0));
  }

  return 0;
}

/***************************************************************************/
